package com.m3958.firstgwt.server.camel;


import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Source;

import org.apache.camel.CamelExecutionException;
import org.apache.camel.Exchange;
import org.apache.camel.Handler;
import org.apache.camel.Header;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.language.mvel.MVEL;
import org.apache.commons.lang.StringUtils;


import com.google.inject.Inject;
import com.m3958.firstgwt.server.model.AsyncTask;
import com.m3958.firstgwt.server.utils.ServerKeyValueCombine;




public class ClonePage{
	
//	jo.element("dowhat", reqPs.getStringValue("dowhat"));
//	jo.element("url", reqPs.getStringValue("url"));
//	jo.element("siteId", reqPs.getStringValue("siteId"));
//	jo.element("path", themeroot.getAbsolutePath());
	

	@Inject
	private DefaultCamelContext context;
	
	@Handler
	public void onMessage(Exchange exchange){
//		String body = exchange.getIn().getBody(String.class);
//		JsonParser jp = new JsonParser();
//		JsonElement je = jp.parse(body);
//		JsonObject jo = je.getAsJsonObject();
		
//		String url = jo.get("url").getAsString().trim();
//		String siteThemeRoot = jo.get("path").getAsString().trim();
//		String ofn = jo.get("fn") == null ? "" : jo.get("fn").getAsString().trim();
		
		try {
			AsyncTask at = exchange.getIn().getBody(AsyncTask.class);
			String s = at.getTaskDescript();
			ServerKeyValueCombine skvc = new ServerKeyValueCombine(s);
			

			
			String url = skvc.getStringValue("url").trim();
			String siteThemeRoot = skvc.getStringValue("path").trim();
			String ofn = skvc.getStringValue("fn").trim();

			String[] hu = getHostnameUri(url);
			
			String hostname = hu[0];
			String uri = hu[1];
			
			final String pageUrl = hostname + uri;
			
			ProducerTemplate template = context.createProducerTemplate();
			
			Exchange ecc = template.send("http4://localhost",new Processor() {
				@Override
				public void process(Exchange exchange) throws Exception {
					exchange.getIn().setHeader(Exchange.HTTP_URI,"http4://" + pageUrl);
				}
			});
			Message out = ecc.getOut();
			String htmlsrc = out.getBody(String.class);
			
			
			List<String[]> relations = new ArrayList<String[]>();//['img','http://www.51dir.com/abc.jpg','e:/siteroot/5/default/images/abc.jpg'] 
			
			Source ss = new Source(htmlsrc);

			Element base = ss.getFirstElement(HTMLElementName.BASE);
			
			String basePath = null;
			if(base != null){
				String baseHref = base.getAttributeValue("href");
				basePath = getHostnameUri(baseHref)[1];
				if(!basePath.endsWith("/"))basePath = basePath + "/";
			}
			
			List<Element> imgs = ss.getAllElements(HTMLElementName.IMG);
			
			List<Element> csses = ss.getAllElements(HTMLElementName.LINK);
			
			List<Element> scripts = ss.getAllElements(HTMLElementName.SCRIPT);
			
			for(Element css:csses){
				String type = css.getAttributeValue("type");
				if("text/css".equalsIgnoreCase(type)){
					String src = css.getAttributeValue("href");
					if(src != null && !src.isEmpty()){
						relations.add(getOneItem(src, "css", basePath, hostname, uri));
					}
				}
			}

			for(Element script:scripts){
				String src = script.getAttributeValue("src");
				if(src != null && !src.isEmpty()){
					relations.add(getOneItem(src, "script", basePath, hostname, uri));
				}
			}
			
			for(Element img : imgs){
				String src = img.getAttributeValue("src");
				if(src != null && !src.isEmpty()){
					relations.add(getOneItem(src, "img", basePath, hostname, uri));
				}
			}
			
			exchange.getOut().setBody(relations);
			exchange.getOut().setHeader("sitetr", siteThemeRoot);
			
			String fn;
			
			if(ofn.isEmpty()){
				fn = guessMainFileName(uri);
			}else{
				if(ofn.endsWith(".ftl")){
					fn = ofn;
				}else{
					fn = ofn + ".ftl";
				}
			}
			template.sendBodyAndHeader("file://" + siteThemeRoot,htmlsrc,Exchange.FILE_NAME,fn);
		} catch (CamelExecutionException e) {
			e.printStackTrace();
		}
	}
	
	private String[] getOneItem(String src,String type,String basePath,String hostname,String uri){
		String[] relation = new String[3];
		relation[0] = type;
		if(src == null){
			;
		}else if(src.startsWith("http://")){
			String[] hu = getHostnameUri(src);
			relation[1] = hu[0] + hu[1];
			relation[2] = hu[1];
		}else if(src.startsWith("/")){
			relation[1] = hostname + src;
			relation[2] = src;
		}else if(src.startsWith("../")){//相对于当前uri
			if(basePath == null){
				String s = getRelativeUri(uri, src);
				relation[1] = hostname + s;
				relation[2] = s;
			}else{
				;
			}
		}else{
			if(basePath == null){//相对于当前请求的url定位。
				;
			}else{
				String s = basePath + src;
				relation[1] = hostname + s;
				relation[2] = s;
			}
		}
		
		if(relation[2] != null){
			int qmi = relation[2].indexOf("?"); 
			if(qmi != -1){
				relation[2] = relation[2].substring(0,qmi);
			}
		}
		return  relation;
	}
	
	private String getRelativeUri(String uri,String ruri){
		
		// /a => ['','a']去掉最后一个
		String[] uris = uri.split("/");
		int uriSeg = uris.length;
		if(uriSeg < 2)uriSeg = 2;
//		if(uris.length == 0){ //单独一个/
//			
//		}else if(uris.length == 1){ //不会出现这种可能
//			;
//		}else{
//			
//		}
		
		//case 1: /a/b.txt ../c/c.txt
		int i = 0;
		while(ruri.startsWith("../")){
			ruri= ruri.substring(3);
			i++;
		}
		
		int j = uriSeg - i - 1;
		
		if(j < 2)return "/" + ruri;
		
		String[] result = new String[j + 1];
		for(int ii=0;ii < j;ii++){
			result[ii] = uris[ii]; 
		}
		result[j] = ruri;
		return StringUtils.join(result,"/");
	}
	
	
	private String[] getHostnameUri(String url){
		int i = url.indexOf("//");
		if(i != -1){
			url = url.substring(i+2);
		}
		
		i = url.indexOf("?");
		if(i != -1){
			url = url.substring(0, i);
		}
		
		String[] ss = new String[2];
		int i1 = url.indexOf("/");//-- www.m3958.com/section/1
		
		if(i1 == -1){
			ss[0] = url;
			ss[1] = "/";
		}else{
			ss[0] = url.substring(0, i1);
			ss[1] = url.substring(i1);
		}
		return ss;
	}
	
	
	private String guessMainFileName(String uri){//-- /section/1
		if("/".equals(uri)){
			return "index.ftl";
		}
		
		String[] ss = uri.split("/");
		String fn = null;
		int i = ss.length - 1;
		for(;i>-1;i--){
			if(ss[i].trim().length() > 0){
				fn = ss[i];
				break;
			}
		}
		if(fn != null){
			int ix = fn.lastIndexOf(".");
			if(ix == -1){
				fn = fn + ".ftl";
			}else{
				fn = fn.substring(0, ix) + ".ftl";
			}
		}else{
			fn = "index.ftl";
		}
		return fn;
	}
	
	public void processStatic(Exchange exchange){
		//图片，css，js。
		
		//http://news.liguoli.com/NewsNew.aspx，那么里面的css存在一个路径
		//<base href="http://news.liguoli.com/" />那么Css/Main.css就是相对于根目录，Main.css里面的url就是相对于Main.css的位置。

	}
	
	public void processImg(@Header("sitetr") String siteThemeRoot, @MVEL("request.body[1]") final String pageUrl,@MVEL("request.body[2]") String saveFileName){
		ProducerTemplate template = context.createProducerTemplate();
		
		//in-out pattern.
    	Exchange ecc = template.send("http4://localhost",new Processor() {
			@Override
			public void process(Exchange exchange) throws Exception {
				exchange.getIn().setHeader(Exchange.HTTP_URI,"http4://" + pageUrl);
			}
		});
    	template.sendBodyAndHeader("file://" + siteThemeRoot,ecc.getOut().getBody(),Exchange.FILE_NAME,saveFileName);

	}
	
	public void processCss(@Header("sitetr") String siteThemeRoot, @MVEL("request.body[1]") final String pageUrl,@MVEL("request.body[2]") String saveFileName,Exchange exchange){
		ProducerTemplate template = context.createProducerTemplate();
		
		//in-out pattern.
    	Exchange ecc = template.send("http4://localhost",new Processor() {
			@Override
			public void process(Exchange exchange) throws Exception {
				exchange.getIn().setHeader(Exchange.HTTP_URI,"http4://" + pageUrl);
			}
		});
    	
    	Message out = ecc.getOut();
    	String c = out.getBody(String.class);
    	List<String[]> relations = new ArrayList<String[]>();
    	//url(../Images/lian.gif)
    	Pattern p = Pattern.compile("url\\s*?\\(['\"\\s]*(.*?)['\"\\s]*\\)");
    	Matcher m = p.matcher(c);
    	String[] hu = getHostnameUri(pageUrl);
    	while(m.find()){
    		String url = m.group(1);
    		relations.add(getOneItem(url, "img", null, hu[0], hu[1]));
    	}
    	exchange.getOut().setHeader("sitetr", siteThemeRoot);
    	exchange.getOut().setBody(relations);
    	template.sendBodyAndHeader("file://" + siteThemeRoot,c,Exchange.FILE_NAME,saveFileName);
	}
	
	public void processScript(@Header("sitetr") String siteThemeRoot, @MVEL("request.body[1]") final String pageUrl,@MVEL("request.body[2]") String saveFileName){
		ProducerTemplate template = context.createProducerTemplate();
		
		//in-out pattern.
    	Exchange ecc = template.send("http4://localhost",new Processor() {
			@Override
			public void process(Exchange exchange) throws Exception {
				exchange.getIn().setHeader(Exchange.HTTP_URI,"http4://" + pageUrl);
			}
		});
    	Message out = ecc.getOut();
    	String c = out.getBody(String.class);
    	
    	template.sendBodyAndHeader("file://" + siteThemeRoot,c,Exchange.FILE_NAME,saveFileName);
	}
	
	public void processOthers(Exchange exchange){
		;
	}
}
